/**
* @brief fat buffer
 * @author xiaoyao
 * @file fatbuffer.c
 * @version V0.01
 * @date 2024-08-31
 */
#include "fatbuffer.h"

#include <stdlib.h>
#include <string.h>


int fatbuffer_init(struct fatbuffer_s* fb)
{
    if (fb == NULL)
    {
        return -1;
    }

    fb->buffer = (unsigned char*)malloc(FATBUFFER_FIRST_SIZE);
    if (fb->buffer == NULL)
    {
        fb->size = 0;
        fb->count = 0;
        return -2;
    }

    memset(fb->buffer, 0, FATBUFFER_FIRST_SIZE);
    fb->size = FATBUFFER_FIRST_SIZE;
    fb->count = 0;

    return 0;
}

int fatbuffer_append(struct fatbuffer_s* fb, unsigned char* buf, unsigned int len)
{
    unsigned int newsize = 0;
    int i = 0;

    if (fb == NULL || buf == NULL)
    {
        return -1;
    }

    if (len == 0)
    {
        return 0;
    }

    if (fb->buffer == NULL)
    {
        return -2;
    }

    if (fb->count + len > fb->size)
    {
        newsize = FATBUFFER_FIRST_SIZE;
        while (1)
        {
            if (newsize > (fb->count + len))
            {
                break;
            }
            else
            {
                newsize = newsize * 2;
            }
        }

        fb->buffer = (unsigned char*)realloc(fb->buffer, newsize);
        if (fb->buffer == NULL)
        {
            return -2;
        }
        fb->size = newsize;
    }
    memcpy(fb->buffer + fb->count, buf, len);
    fb->count += len;

    return 0;
}

int fatbuffer_delete(struct fatbuffer_s* fb)
{
    if (fb->buffer != NULL)
    {
        free(fb->buffer);
        fb->buffer = NULL;
        fb->size = 0;
        fb->count = 0;
    }
    return 0;
}

int fatbuffer_clear(struct fatbuffer_s* fb)
{
    if (fb->buffer != NULL)
    {
        memset(fb->buffer, 0, fb->size);
        fb->count = 0;
    }
    return 0;
}

#if FATBUFER_TEST_ENABLE
#include <stdio.h>

void fatbufer_hexdump(struct fatbuffer_s* fb)
{
    int i = 0;
    for (i = 0; i < fb->count; i++)
    {
        printf("%02x ", fb->buffer[i]);
    }
}

void fatbuffer_test(void)
{
    struct fatbuffer_s fb;
    unsigned char buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    fatbuffer_init(&fb);
    fatbuffer_append(&fb, buf, 10);
    fatbuffer_append(&fb, buf, 3);
    fatbufer_hexdump(&fb);
    fatbuffer_delete(&fb);
}
#endif
